package com.cy.pj.goods.dao;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Repository
public class DefaultGoodsDao implements GoodsDao{
    @Autowired
    private DataSource dataSource;

    //初始化一个日志对象（所有的类都在org.slf4j包中）
    //在哪个类创建日志对象，我们的getLogger方法内部的对象就为哪个类的字节码对象
    private static final Logger log = LoggerFactory.getLogger(DefaultGoodsDao.class);
    //行映射
    Map<String,Object> rowMap(ResultSetMetaData rsmd,ResultSet rs) throws SQLException {
        Map<String,Object> map=new HashMap<>();
        for(int i=1;i<=rsmd.getColumnCount();i++){//循环取出所有字段的值
            map.put(rsmd.getColumnName(i),rs.getObject(rsmd.getColumnName(i)));
        }
        return map;
    }
    //
    public void close(ResultSet rs,Statement stat,Connection con){
        if(rs != null)  try { rs.close(); } catch (SQLException e) {}
        if(stat != null)  try { stat.close(); } catch (SQLException e) {}
        if(con != null)  try { con.close(); } catch (SQLException e) {}
    }
    @Override
    public List<Map<String, Object>> findGoods()  {
        Connection con = null;
        Statement stat = null;
        ResultSet rs = null;
        String sql = "select * from tb_goods";
        try {
            //1.获取链接
            con = dataSource.getConnection();
            //2.创建连接对象
            stat = con.createStatement();
            //3.发送sql
            rs = stat.executeQuery(sql);
            //4.处理结果
            List<Map<String,Object>> list=new ArrayList<>();
            ResultSetMetaData rsmd = rs.getMetaData(); //获取结果集的元数据（描述数据的）
            while (rs.next()){//循环一次取一行，行映射
//                Map<String,Object> map = new HashMap();
//                map.put("id",rs.getInt("id"));
//                map.put("name", rs.getString("name"));
//                map.put("remark", rs.getString("remark"));
//                map.put("createdTime", rs.getTimestamp("createdTime"));
//                list.add(map);
                //映射方案2
                list.add(rowMap(rsmd,rs));
            }
            return list;
        } catch (SQLException e) {
//            e.printStackTrace();
            //记录日志（一般异常日志借助log.error方法进行记录）
            log.error("异常，{}",e.getMessage());//{}表示占位符
//            return null;
            throw new RuntimeException("数据查询失败"+e.getMessage());
        }finally {
            //5.释放资源
            close(rs,stat,con);
//            if(rs != null)  try { rs.close(); } catch (SQLException e) {}
//            if(stat != null)  try { stat.close(); } catch (SQLException e) {}
//            if(con != null)  try { con.close(); } catch (SQLException e) {}
        }
    }
}

/**
 * 代码优缺点？
 * 优点：
 * 1）使用了连接池，优化了建立连接的过程，提高了数据访问性能。
 * 2）代码简单（就是一些流水代码）
 * 3）使用了map做映射，简化了pojo对象定义
 * 缺点：
 * 1）可重用性比较差（可以将释放代码进行封装）
 * 2）行映射不灵活
 * 3）异常的处理不能简单地打印一下，然后返回null值
 * 4）Map封装数据时值的类型不可控（建议后续修改为pojo对象）
 * 5）对共性代码进行封装，特性代码进行提取
 */